package com.sanyou.controller;

import cn.hutool.core.util.ObjUtil;
import com.google.common.collect.Lists;
import com.sanyou.enums.IsOk;
import com.sanyou.pojo.*;
import com.sanyou.pojo.param.CopperParticleHistoryParam;
import com.sanyou.pojo.vo.*;
import com.sanyou.service.*;
import com.sanyou.utils.DateUtils;
import com.sanyou.utils.JSONResult;
import com.sanyou.utils.PagedResult;
import com.sanyou.utils.TimeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.IOException;
import java.sql.Array;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * 铜粒子检测相关的api接口
 */
@Api(value = "铜粒子相关的接口",tags = {"铜粒子数据相关的Controller"})
@CrossOrigin
@RestController
@RequestMapping("/copper")
public class CopperController {

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private UserEquipmentService userEquipmentService;

    @Resource
    private CopperParticleService copperParticleService;

    @Resource
    private UserService userService;

    @Resource
    private DataInfoService dataInfoService;

    @Autowired
    private DataAuthorityService dataAuthorityService;
    /**
     * 从redis数据库获取当天铜粒子实时检测数据
     * @param copperRtDataVo
     * @param page
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "判断铜粒子实时数据", notes = "判断铜粒子实时数据")
    @PostMapping("/copperRtData")
    public JSONResult copperRtData(@RequestBody CopperRtDataVo copperRtDataVo , Integer page, Integer pageSize){
        if(page == null)
            page = 1;
        if(pageSize == null)
            pageSize = 20;
        if(copperRtDataVo == null || StringUtils.isBlank(copperRtDataVo.getDeviceNo()))
            return JSONResult.errorMsg("设备编号不能为空!");
        if(StringUtils.isBlank(copperRtDataVo.getUserId()))
            return JSONResult.errorMsg("用户id不能为空!");
        //boolean haveAuth = userEquipmentService.checkAuth(copperRtDataVo.getDeviceNo(), copperRtDataVo.getUserId());
        boolean haveAuth = dataAuthorityService.checkAuthorityOfEquipmentByNo(copperRtDataVo.getUserId(),copperRtDataVo.getDeviceNo());

        if (haveAuth){
            IsOk isOk1;
            if (copperRtDataVo.getFlag()==1) isOk1= IsOk.OK;else isOk1=IsOk.NG;
            try{
                //PagedResult result=copperParticleService.getAllRecordsFromCache(copperRtDataVo.getDeviceNo(),isOk1,"","",page,pageSize);
                PagedResult result=copperParticleService.getCopperParticleRecordsOfToday(copperRtDataVo.getDeviceNo(), isOk1,null,null,page,pageSize);
                return JSONResult.ok(result);
            }
            catch (Exception e){
                e.printStackTrace();
                return JSONResult.errorMsg("数据获取失败："+e.getMessage());
            }
        }
        else{
            return JSONResult.build(503, "没有设备权限", null);
        }
    }
    /**
     * 根据用户id确定设备权限返回铜粒子当天失败编码数量
     * @param userId
     * @param equipNo
     * @return   还没加
     */
    @ApiOperation(value = "获取铜粒子当天编码读取失败数量", notes = "获取铜粒子当天编码读取失败数量")
    @PostMapping("/getFailNumber")
    public JSONResult getFailNumber(@RequestHeader(value="userId") String userId,String equipNo){
        //数据权限校验
        if(!dataAuthorityService.checkAuthorityOfEquipmentByNo(userId,equipNo)){
            return JSONResult.errorMsg("用户无该设备的访问权限！");
        }
        try {
            //List<CopperParticleCheckRecord> result1=copperParticleService.getAllRecordsFromCache(equipNo,null,"0000000","");
            List<CopperParticleCheckRecord> result1=copperParticleService.getCopperParticleRecordsOfToday(equipNo,null,"0000000",null);
            return JSONResult.ok(result1.size());
        }
        catch (Exception e){
            e.printStackTrace();
            return JSONResult.errorMsg("数据获取失败："+e.getMessage());
        }
    }
    /**
     * 从redis数据库获取当天铜粒子实时检测数据饼图
     * @param copperRtDataVo
     * @return
     */
    @ApiOperation(value = "获取铜粒子实时饼图数据", notes = "获取铜粒子实时饼图数据")
    @PostMapping("/copperPieRtData")
    public JSONResult copperPieRtData(@RequestBody CopperRtDataVo copperRtDataVo){
        if(copperRtDataVo == null || StringUtils.isBlank(copperRtDataVo.getDeviceNo()))
            return JSONResult.errorMsg("设备编号不能为空!");
        int size3,size4;
        List<CopperRtDataVo> list=new ArrayList<>();
        CopperRtDataVo copperRtDataVo1=new CopperRtDataVo();
        CopperRtDataVo copperRtDataVo2=new CopperRtDataVo();
        if(StringUtils.isBlank(copperRtDataVo.getUserId()))
            return JSONResult.errorMsg("用户id不能为空!");
            //boolean haveAuth = userEquipmentService.checkAuth(copperRtDataVo.getDeviceNo(),copperRtDataVo.getUserId());
            boolean haveAuth = dataAuthorityService.checkAuthorityOfEquipmentByNo(copperRtDataVo.getUserId(),copperRtDataVo.getDeviceNo());
            if(haveAuth){
                try {
                     //size3=(int)copperParticleService.getAllRecordsFromCacheLength(copperRtDataVo.getDeviceNo(), IsOk.OK,"","");
                     //size4=(int)copperParticleService.getAllRecordsFromCacheLength(copperRtDataVo.getDeviceNo(), IsOk.NG,"","");
                    size3=copperParticleService.getCopperParticleRecordsOfToday(copperRtDataVo.getDeviceNo(), IsOk.OK,null,null).size();
                    size4=copperParticleService.getCopperParticleRecordsOfToday(copperRtDataVo.getDeviceNo(), IsOk.NG,null,null).size();
                } catch (Exception e){
                    return JSONResult.errorMsg("数据获取失败："+e.getMessage());
                }
                copperRtDataVo1.setName("合格");
                copperRtDataVo1.setValue(size3);
                copperRtDataVo2.setName("不合格");
                copperRtDataVo2.setValue(size4);
                list.add(copperRtDataVo1);
                list.add(copperRtDataVo2);
            }else {
                return JSONResult.build(503,"没有设备权限",null);
            }
            return JSONResult.ok(list);
    }
    /**
     *下载指定设备下根据铜粒子状态合格/不合格状态下载对应数据
     * @param equipNo
     * @param flag 1:代表合格，0代表不合格
     * @return
     */
    @ApiOperation("下载铜粒子实时数据")
    @GetMapping("/copperRtDownload")
    public void download(String equipNo, int flag, HttpServletResponse response) throws IOException{
        IsOk isOk1;
        if (flag==1)
            isOk1=IsOk.OK;
        else
            isOk1=IsOk.NG;
        List<CopperParticleCheckRecord> list1=new ArrayList<>();
        //List<CopperParticleCheckRecord> list = copperParticleService.getAllRecordsFromCache(equipNo,isOk);
        try{
            //list1 = copperParticleService.getAllRecordsFromCache(equipNo,isOk1,"","");
            list1 = copperParticleService.getCopperParticleRecordsOfToday(equipNo,isOk1,null,null);
        }catch (Exception e){
            System.out.println("Exception:"+e.getMessage());
        }
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("sheet1");
        sheet.setColumnWidth(0,21*256);
        sheet.setColumnWidth(1,21*256);
        sheet.setColumnWidth(2,21*256);
        sheet.setColumnWidth(3,41*256);
        sheet.setColumnWidth(4,16*256);
        sheet.setColumnWidth(5,16*256);
        sheet.setColumnWidth(6,21*256);
        sheet.setColumnWidth(7,21*256);
        sheet.setColumnWidth(8,46*256);
        sheet.setColumnWidth(9,46*256);
        long timeMillis = System.currentTimeMillis();
        String fileName = timeMillis + ".xls";
        int  rowNum = 1;
        String[] headers = {"设备编号","产品编号","类型","时间","A面面积","B面面积","A面是否合格","B面是否合格","A面图片","B面图片"};
        HSSFRow row = sheet.createRow(0);
        for(int i=0;i<headers.length;i++){
            HSSFCell cell = row.createCell(i);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        for (CopperParticleCheckRecord copperParticleCheckRecord : list1) {
            HSSFRow row1 = sheet.createRow(rowNum);
            row1.createCell(0).setCellValue(copperParticleCheckRecord.getDeviceNo());
            row1.createCell(1).setCellValue(copperParticleCheckRecord.getProductCode());
            row1.createCell(2).setCellValue(copperParticleCheckRecord.getType());
            row1.createCell(3).setCellValue(format.format(copperParticleCheckRecord.getDatetime()));
            row1.createCell(4).setCellValue(copperParticleCheckRecord.getaArea());
            row1.createCell(5).setCellValue(copperParticleCheckRecord.getbArea());
            row1.createCell(6).setCellValue(copperParticleCheckRecord.getaIsOk());
            row1.createCell(7).setCellValue(copperParticleCheckRecord.getbIsOk());
            row1.createCell(8).setCellValue(copperParticleCheckRecord.getaImageName());
            row1.createCell(9).setCellValue(copperParticleCheckRecord.getbImageName());
            rowNum++;
        }

        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        response.flushBuffer();
        workbook.write(response.getOutputStream());
        workbook.close();
    }
    /**
     * 阴极铜根据开始时间，结束时间，车间号，间隔时间阴极铜历史记录，按日期间隔聚合总数
     * @param copperParticleHistoryParam
     * @return
     */
    @ApiOperation(value = "获取铜粒子历史数据", notes = "获取铜粒子历史数据")
    @PostMapping("/copperHistoryData")
    public JSONResult copperHistoryData(@Valid @RequestBody CopperParticleHistoryParam copperParticleHistoryParam){

        List<CopperParticleHistoryVo> list = copperParticleService.getHistoryList(copperParticleHistoryParam.getSubFactoryNo(),
                copperParticleHistoryParam.getStartDate(),
                copperParticleHistoryParam.getEndDate(),
                copperParticleHistoryParam.getInterval());

        return JSONResult.ok(list);
    }
    /**
     * 阴极铜根据开始时间，结束时间，车间号，间隔时间获取详细阴极铜历史记录
     * @param copperParticleHistoryParam
     * @return
     */
    @ApiOperation(value = "获取每条铜粒子历史数据", notes = "获取每条铜粒子历史数据")
    @PostMapping("/copperHistoryList")
    public JSONResult copperHistoryList(@Valid @RequestBody CopperParticleHistoryParam copperParticleHistoryParam,
                                        @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
                                        @RequestParam(value = "page", required = false, defaultValue = "1") Integer page){
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(copperParticleHistoryParam.getEndDate());
        calendar.add(calendar.DATE,1); //把日期往后增加一天,整数  往后推,负数往前移动
        Date date=calendar.getTime(); //这个时间就是日期往后推一天的结果
        System.out.println(date);
        return JSONResult.ok(copperParticleService.listHistoryRecord(copperParticleHistoryParam.getSubFactoryNo(),
                copperParticleHistoryParam.getStartDate(),
                date, size, page));
    }
    /**
     * 下载特定车间的一段时间内铜粒子的历史数据
     * @param startDate
     * @param endDate
     * @param subFactoryNo
     * @return
     */
    @ApiOperation("下载铜粒子历史数据")
    @GetMapping("/downloadHistoryData")
    public void downloadHistoryData(String startDate, String endDate, String subFactoryNo, HttpServletResponse response) throws IOException, ParseException {

        DateFormat fmt = new SimpleDateFormat ("yyyy-MM-dd");
        List<CopperParticleHistoryVo> copperParticleHistoryList = copperParticleService.getHistoryList(subFactoryNo,
                fmt.parse(startDate), fmt.parse(endDate), 1);

        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("sheet1");
        sheet.setColumnWidth(0,41*256);
        sheet.setColumnWidth(1,21*256);
        sheet.setColumnWidth(2,21*256);

        String[] headers = {"日期", "合格", "不合格"};
        HSSFRow row = sheet.createRow(0);
        for(int i=0;i<headers.length;i++){
            HSSFCell cell = row.createCell(i);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }

        int  rowNum = 1;
        for (CopperParticleHistoryVo copperParticleHistoryVo : copperParticleHistoryList) {
            HSSFRow row1 = sheet.createRow(rowNum);
            row1.createCell(0).setCellValue(copperParticleHistoryVo.getDate().toString());
            row1.createCell(1).setCellValue(copperParticleHistoryVo.getQualifiedCopperNum());
            row1.createCell(2).setCellValue(copperParticleHistoryVo.getUnqualifiedCopperNum());
            rowNum++;
        }

        long timeMillis = System.currentTimeMillis();
        String fileName = timeMillis + ".xls";
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        response.flushBuffer();
        workbook.write(response.getOutputStream());
        workbook.close();
    }
    /**
     * 分页获取某设备在某天的铜粒子的原始数据信息
     * @param copperParticleReqVo
     * @param page
     * @param size
     * @return
     */
    @ApiOperation("获取原始数据")
    @PostMapping("/rawData")
    public JSONResult getList(@RequestBody CopperParticleReqVo copperParticleReqVo,
                              @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
                              @RequestParam(value = "page", required = false, defaultValue = "1") Integer page)
    {
        if (!ObjUtil.isAllNotEmpty(copperParticleReqVo.getDeviceNo(), copperParticleReqVo.getStartTime()))
            return JSONResult.errorMsg("传入参数不能为空!");

        if (copperParticleService.date2LocalDate(copperParticleReqVo.getStartTime()).isAfter(LocalDate.now())){
            return JSONResult.errorMsg("设定时间非法");
        }

        try{
            return JSONResult.ok(copperParticleService.getList(copperParticleReqVo, size, page));
        } catch (Exception e){
            return JSONResult.errorMsg("Exception:"+e.getMessage());
        }
    }

    /**
     * 获取某设备在某天的铜粒子检测信息按小时聚合
     * @param copperParticleReqVo
     * @return
     */
    @ApiOperation(value = "获取时间结果展示数据", notes = "获取时间结果展示数据")
    @PostMapping("/copperTimeData")
    public JSONResult getTimeData(@RequestBody CopperParticleReqVo copperParticleReqVo)

    {
        if (!ObjUtil.isAllNotEmpty(copperParticleReqVo.getDeviceNo(), copperParticleReqVo.getStartTime()))
            return JSONResult.errorMsg("传入参数不能为空!");

        Boolean istoday = new TimeUtils().isToday(copperParticleReqVo.getStartTime());
        Map<Integer, Integer> result = new HashMap<>();

//        if(istoday){
//            //当日数据redis
//            result  = copperParticleService.getRtTimeDistribution(copperParticleReqVo.getDeviceNo());
//        }else {
//            //历史数据DataBase
//            result = copperParticleService.getHisTimeDistribution(copperParticleReqVo.getDeviceNo(),copperParticleReqVo.getStartTime());
//        }
        result = copperParticleService.getHisTimeDistribution(copperParticleReqVo.getDeviceNo(),copperParticleReqVo.getStartTime());

        return JSONResult.ok(result);
    }

    /**
     * 用户主页阴极铜表面缺陷检测和不合格类型数据
     * @param user
     * @return
     */
    @ApiOperation(value = "获取主页展示数据", notes = "获取主页展示数据")
    @PostMapping("/homePageDefect")
    public JSONResult getDefectInfo(@RequestBody User user) throws Exception {
        if (!ObjUtil.isAllNotEmpty(user.getId()))
            return JSONResult.errorMsg("传入参数不能为空!");

        String subFacId = userService.getUserById(user.getId()).getSubFactoryId();
        List<Equipment> equipmentList = equipmentService.getEquipmentFactoryListbySubFac(subFacId);

        //删除list中的重复设备
        Set<Equipment> equipSet = new TreeSet<Equipment>(Comparator.comparing(Equipment::getEquipNo));
        equipSet.addAll(equipmentList);

        Map<String,Object> map = new HashMap<String,Object>();
        Map<String,Long> typemap = new HashMap<String,Long>();

        long total = 0;
        long oKNum= 0;
        long nGNum = 0;
        //从数据字典找出
        List<DataInfoDetail> particle_typeList = dataInfoService.getDataInfoDetailsById("2","1");

        for (DataInfoDetail type : particle_typeList) {
            typemap.put(type.getDataName(),0L);
        }

        map.put("type",typemap);

        for (Equipment equip : equipSet) {
            CopperParticleRtVo copperParticleRtVo = new CopperParticleRtVo(equip.getEquipNo(),null, "", "");

            try {

                //取总数，OK,NG

                //total += copperParticleService.getAllRecordsFromCacheLength(copperParticleRtVo.getDeviceNo(), null, copperParticleRtVo.getProductNo(), copperParticleRtVo.getParticleType());
                //oKNum += copperParticleService.getAllRecordsFromCacheLength(copperParticleRtVo.getDeviceNo(), IsOk.OK, copperParticleRtVo.getProductNo(), copperParticleRtVo.getParticleType());
                //nGNum += copperParticleService.getAllRecordsFromCacheLength(copperParticleRtVo.getDeviceNo(), IsOk.NG, copperParticleRtVo.getProductNo(), copperParticleRtVo.getParticleType());

                total += copperParticleService.getCopperParticleRecordsOfToday(copperParticleRtVo.getDeviceNo(),null,copperParticleRtVo.getProductNo(), copperParticleRtVo.getParticleType()).size();
                oKNum += copperParticleService.getCopperParticleRecordsOfToday(copperParticleRtVo.getDeviceNo(),IsOk.OK,copperParticleRtVo.getProductNo(), copperParticleRtVo.getParticleType()).size();
                nGNum += copperParticleService.getCopperParticleRecordsOfToday(copperParticleRtVo.getDeviceNo(),IsOk.NG,copperParticleRtVo.getProductNo(), copperParticleRtVo.getParticleType()).size();
                map.put("total",total);
                map.put("oKNum",oKNum);
                map.put("nGNum",nGNum);

                //粒子类型分类统计
                //List<CopperParticleCheckRecord> recordList = copperParticleService.getAllRecordsFromCache(copperParticleRtVo.getDeviceNo(), IsOk.NG, copperParticleRtVo.getProductNo(), copperParticleRtVo.getParticleType());
                List<CopperParticleCheckRecord> recordList = copperParticleService.getCopperParticleRecordsOfToday(copperParticleRtVo.getDeviceNo(), IsOk.NG,copperParticleRtVo.getProductNo(),copperParticleRtVo.getParticleType());
                recordList.forEach(record->{
                    String type = record.getType();
                    if (typemap.get(type)!=null) typemap.put(type,typemap.get(type)+1);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return JSONResult.ok(map);
    }
    /**
     * 原始数据中编码更正分页获取某天的编码为0000000的阴极板数据
     * @param equipNo
     * @param startTime
     * @param endTime
     * @return
     */
    @ApiOperation(value = "获取时间在startTime~endTime之间的所有无法识别编码(编码全0)的铜粒子检测记录")
    @GetMapping("/copperParticleDataWithoutProductNo")
    public JSONResult getCopperParticleDataWithoutProductNo(@RequestParam String equipNo,
                                                            @RequestParam String startTime,
                                                            @RequestParam String endTime,
                                                            @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
                                                            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page){
        if (!(DateUtils.isLegalDate(startTime.length(), startTime, "yyyy-MM-dd HH:mm:ss") && DateUtils.isLegalDate(endTime.length(), endTime, "yyyy-MM-dd HH:mm:ss")))
            return JSONResult.errorMsg("时间格式错误");

        if(equipNo == null || equipNo.length()==0){
            return JSONResult.errorMsg("设备编号不能为空");
        }


        /**
         * 获取时间在startTime~endTime之间的所有无法识别编码(编码全0)的铜粒子检测记录
         */
        PagedResult result = copperParticleService.getCopperParticleRecords(
                equipNo,
                DateUtils.stringToDate(startTime),
                DateUtils.stringToDate(endTime),
                null,
                "0000000",
                null,
                page,
                size);

        return JSONResult.ok(result);
    }
    /**
     * 原始数据中编码更正阴极板数据，根据product_code更新
     * @param records
     * @return
     */
    @ApiOperation(value = "根据ID更新铜粒子检测记录的阴极板编号")
    @PostMapping("/updateProductNoOfCopperParticleRecords")
    public JSONResult updateProductNoOfCopperParticleRecords(@RequestBody List<CopperParticleCheckRecord> records){
        for(CopperParticleCheckRecord record:records){
            if(record.getId() == null || StringUtils.isEmpty(record.getProductCode())){
                continue;
            }
            try {
                copperParticleService.updateProductNoOfCopperParticleCheckRecord(record.getId(),record.getProductCode());
            } catch (Exception e) {

            }
        }


        return JSONResult.ok("更新成功");
    }

}
